package org.grottarossa.ui.core.components;

import java.util.ArrayList;
import java.util.Hashtable;

import org.grottarossa.data.DataProvider;
import org.grottarossa.data.Query;
import org.grottarossa.data.Query.ResultSetType;
import org.grottarossa.data.QueryFilter;
import org.grottarossa.data.exception.QueryException;
import org.grottarossa.template.data.pojo.table.Table;
import org.grottarossa.ui.core.container.TableContainer;


import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.terminal.gwt.client.Console;
import com.vaadin.ui.Field;
import com.vaadin.ui.NativeSelect;

public class TMSNativeSelect extends NativeSelect implements ValueChangeListener, ITMSControl
{
	/**
	 *
	 */
	private static final long serialVersionUID = -8168265169772840965L;

	private ITMSControl m_dependentField;
	private String m_relatedField;
	private String filterId;
	private Query query;
	private QueryFilter m_dependentFieldExtraFilter;
	private Hashtable<String, Field> m_dependentFieldExtraFilterFields;
	private DataProvider m_dataProvider;

	public TMSNativeSelect(DataProvider dataProvider, String errorMsg)
	{
		initialize(dataProvider, errorMsg);
	}

	public TMSNativeSelect(DataProvider dataProvider, String caption, String errorMsg)
	{
		initialize(dataProvider, errorMsg);
		setCaption(caption);
	}


	private void initialize(DataProvider dataProvider, String errorMsg)
	{
		m_dataProvider = dataProvider;
		setNullSelectionAllowed(false);
		setWidth("100%");
		setRequired(false);
		setRequiredError(errorMsg);
		addListener((ValueChangeListener)this);
		setImmediate(true);
	}

	@Override
	public void valueChange(com.vaadin.data.Property.ValueChangeEvent event)
	{
		if(m_dependentField != null && query != null)
		{
			Object value = event.getProperty().getValue();

			QueryFilter filter = (m_dependentFieldExtraFilter == null) ?
					new QueryFilter() : m_dependentFieldExtraFilter;

			if(m_dependentFieldExtraFilterFields != null)
			{
				for(String filterName : m_dependentFieldExtraFilterFields.keySet())
				{
					filter.addFilter(filterName).
						add(m_dependentFieldExtraFilterFields.get(filterName).getValue());
				}
			}

			filter.addFilter(filterId).add(value);

			try
			{
				m_dependentField.populate(m_dataProvider.getSource(m_relatedField, filter));
			}
			catch (Exception e)
			{
				e = e;
			}
		}
	}

	public TMSNativeSelect attachDependentControl(ITMSControl dependentField, String field)
	{
		m_dependentField = dependentField;
		m_relatedField = field;
		return this;
	}

	public TMSNativeSelect attachDependentControl(ITMSControl dependentField, String field, QueryFilter extraFilter)
	{
		m_dependentField = dependentField;
		m_relatedField = field;
		m_dependentFieldExtraFilter = extraFilter;
		return this;
	}

	public TMSNativeSelect attachDependentControl(ITMSControl dependentField, String field, Hashtable<String, Field> extraFilterFields)
	{
		m_dependentField = dependentField;
		m_relatedField = field;
		m_dependentFieldExtraFilterFields = extraFilterFields;
		return this;
	}

	public void detatchDependentControl()
	{
		m_dependentField = null;
		m_relatedField = null;
	}

	public void populate(Query query) throws QueryException
	{
		if(query == null)
			return;

		this.query = query;

		removeAllItems();

		for(Object property : super.items.getContainerPropertyIds())
		{
			super.items.removeContainerProperty(property);
		}

		Table data = (Table)query.execute(ResultSetType.KeyValue);
		setItemCaptionPropertyId(this.query.getMasterPropertyName());

		TableContainer tc = new TableContainer(this.query.getStoragePropertyName());
		tc.setDataTable(data);

		this.setContainerDataSource(tc);
	}

	@Override
	public boolean isEmpty()
	{
		Object value = this.getValue();
		return (value == null) || (value instanceof String && ((String)value).trim().length() == 0);
	}


	public void setFilterId(String filterId) {
		this.filterId = filterId;
	}


	public String getFilterId() {
		return filterId;
	}



}
